package roborally.script;

import java.lang.reflect.InvocationTargetException;

import roborally.model.*;
import roborally.script.composedCondition.*;
import roborally.script.conditionalCommand.*;
import roborally.script.nonConditionalCommand.*;
import roborally.script.singleCommand.*;
import roborally.script.singleCondition.*;

public enum CommandWord {
	//Composed conditions
	
	AND {

		@Override
		public Class<And> getCommandClass() {
			return And.class;
		}

		@Override
		protected Statement getStatement() {
			return new And(new Robot(Orientation.UP,2000,20000), new True(new Robot(Orientation.UP,2000,20000)),new True(new Robot(Orientation.UP,2000,20000)));
		}
		
	},
	OR {

		@Override
		public Class<Or> getCommandClass() {
			return Or.class;
		}

		@Override
		protected Statement getStatement() {
			return new Or(new Robot(Orientation.UP,2000,20000), new True(new Robot(Orientation.UP,2000,20000)),new True(new Robot(Orientation.UP,2000,20000)));
		}
		
	},
	NOT {

		@Override
		public Class<Not> getCommandClass() {
			return Not.class;
		}

		@Override
		protected Statement getStatement() {
			return new Not(new Robot(Orientation.UP,2000,20000), new True(new Robot(Orientation.UP,2000,20000)));
		}
		
	},
	
	//Conditional commands
	
	IF {

		@Override
		public Class<If> getCommandClass() {
			return If.class;
		}

		@Override
		protected Statement getStatement() {
			Robot robot = new Robot(Orientation.UP,2000,20000);
			return new If(robot, new True(robot), new Move(robot), new Move(robot));
		}
		
	},
	WHILE {

		@Override
		public Class<While> getCommandClass() {
			return While.class;
		}

		@Override
		protected Statement getStatement() {
			Robot robot = new Robot(Orientation.UP,2000,20000);
			return new While(robot, new True(robot), new Move(robot));
		}
		
	},
	
	//Nonconditional commands
	
	SEQ {

		@Override
		public Class<Seq> getCommandClass() {
			return Seq.class;
		}

		@Override
		protected Statement getStatement() {
			return new Seq(new Robot(Orientation.UP,2000,20000));
		}
		
	},
	
	//Single commands
	
	MOVE {

		@Override
		public Class<Move> getCommandClass() {
			return Move.class;
		}

		@Override
		protected Statement getStatement() {
			return new Move(new Robot(Orientation.UP,2000,20000));
		}
		
	},
	PICKUP_AND_USE {

		@Override
		public Class<PickupAndUse> getCommandClass() {
			return PickupAndUse.class;
		}

		@Override
		protected Statement getStatement() {
			return new PickupAndUse(new Robot(Orientation.UP,2000,20000));
		}
		
	},
	SHOOT {

		@Override
		public Class<Shoot> getCommandClass() {
			return Shoot.class;
		}

		@Override
		protected Statement getStatement() {
			return new Shoot(new Robot(Orientation.UP,2000,20000));
		}
		
	},
	TURN {

		@Override
		public Class<Turn> getCommandClass() {
			return Turn.class;
		}

		@Override
		protected Statement getStatement() {
			return new Turn(new Robot(Orientation.UP,2000,20000),Direction.CLOCKWISE);
		}
		
	},
	
	//Single conditions
	
	AT_ITEM {

		@Override
		public Class<AtItem> getCommandClass() {
			return AtItem.class;
		}

		@Override
		protected Statement getStatement() {
			return new AtItem(new Robot(Orientation.UP,2000,20000));
		}
		
	},
	AT_WALL {

		@Override
		public Class<AtWall> getCommandClass() {
			return AtWall.class;
		}

		@Override
		protected Statement getStatement() {
			return new AtWall(new Robot(Orientation.UP,2000,20000));
		}
		
	},
	CAN_HIT_ROBOT {

		@Override
		public Class<CanHitRobot> getCommandClass() {
			return CanHitRobot.class;
		}

		@Override
		protected Statement getStatement() {
			return new CanHitRobot(new Robot(Orientation.UP,2000,20000));
		}
		
	},
	ENERGY_AT_LEAST {

		@Override
		public Class<EnergyAtLeast> getCommandClass() {
			return EnergyAtLeast.class;
		}

		@Override
		protected Statement getStatement() {
			return new EnergyAtLeast(new Robot(Orientation.UP,2000,20000),2);
		}
		
	},
	
	TRUE {

		@Override
		public Class<True> getCommandClass() {
			return True.class;
		}

		@Override
		protected Statement getStatement() {
			return new True(new Robot(Orientation.UP,2000,20000));
		}
		
	};
	
	public enum Composed {
		
	}

	public abstract Class<?> getCommandClass();
	protected abstract Statement getStatement();
	public String toString(){
		try {
			return getStatement().toString();
		} catch (Exception e){
			e.printStackTrace();
			return "";
		}
	}
	
}
